/*
 *  Copyright (C) 1993  Robert Davis
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of Version 2, or any later version, of 
 *  the GNU General Public License as published by the Free Software 
 *  Foundation.
 */


static char RCSId[]="$Id: UserTicsPane.m,v 1.4 1993/05/04 16:23:15 davis Exp $";

#import <appkit/Application.h>
#import <appkit/Form.h>
#import <appkit/FormCell.h>
#import <appkit/publicWraps.h>		/* NXBeep() */
#import <appkit/View.h>

#import "CellScrollView.h"
#import "DoubleValueSortedList.h"
#import "EditMatrix.h"
#import "Status.h"
#import "StatusTics.h"
#import "TicCell.h"
#import "TicObject.h"
#import "TicOptionsPanel.h"
#import "UserTicsPane.h"

@interface UserTicsPane (Private)
- _updateControlsForSelectedTic;
@end


@implementation UserTicsPane


- init
{
    [super init];

    [NXApp loadNibSection: "UserTicsPane.nib"
		    owner: self
		withNames: NO
		 fromZone: [self zone]];

    /*  Initialize custom tics CellScrollView  */

    [userScrollView initMatrixCellClass:[TicCell class] cols:1];
    userMatrix = [userScrollView cellMatrix];
    [[userMatrix setAction:@selector(selectTic:)] setTarget:self];

    return self;
}


- (BOOL)updateStatus:aStatus doc:aDoc
{
    BOOL	isEnabled;

    if ([super updateStatus:aStatus doc:aDoc]) {
	int		i;
	int		coord = [doc coord];

	for (i = 0; i < 3; i++)
	    ticsList[i] = [status ticDefsCoord:i];

	[userScrollView loadCol:0 from:ticsList[coord]];

    } else
	[userScrollView loadCol:0 from:nil];

    [self selectTic:self];
    [addTicButton setEnabled:isEnabled = (status? YES:NO)];
    [userTitleForm setEnabled:isEnabled];
    [userValueForm setEnabled:isEnabled];
    [userMatrix setEnabled:isEnabled];
    [deleteTicButton setEnabled:isEnabled = (status &&
					     [userMatrix selectedCell])];
    [modifyTicButton setEnabled:isEnabled];

    return YES;
}


- addTic:sender
{
    int		coord = [doc coord];
    TicObject	*ticObject;
    int		location;
    BOOL	changed = YES;

    ticObject = [[TicObject allocFromZone:[status zone]]
			   initFromString:[userTitleForm stringValueAt:0]
			      doubleValue:[userValueForm doubleValueAt:0]];
    location = [ticsList[coord] addObjectIfDoubleAbsent:ticObject];

    if (location == NX_NOT_IN_LIST) {
	[ticObject free];
	location = [userMatrix selectedRow];
	changed = NO;
	NXBeep();
    }

    [userScrollView loadCol:0 from:ticsList[coord]];
    [userMatrix scrollCellToVisible:location :0];
    [userMatrix selectCellAt:location :0];

    [self selectTic:self];
    if (changed)
	[status reportSettingsChange:self];

    return self;
}


- deleteTics:sender
{
    int		coord = [doc coord];
    int		i;
    int		maxrow = [userMatrix cellCount] - 1;
    int		row = maxrow;
    BOOL	gotRow = NO;

    for (i = maxrow; i >= 0; i--) {
	TicCell *cell = [userMatrix cellAt:i:0];
	if ([cell isHighlighted]) {
	    /*
	     *  If a cell is highlighted, remove (and free) the
	     *  corresponding item from the list of TicObjects.
	     */
	    [[ticsList[coord] removeObject:[cell subObject]] free];

	    if (!gotRow) {
		row = (i == maxrow)? i - 1 :i;
		gotRow = YES;
	    } else
		row--;
	}
    }

    [userScrollView loadCol:0 from:ticsList[coord]];

    [userMatrix selectCellAt: row:0];
    [userMatrix scrollCellToVisible: row:0];
    [self selectTic:self];

    [status reportSettingsChange:self];
    return self;
}


- modifyTic:sender
{
    int		coord = [doc coord];
    TicObject	*tic = [[userMatrix selectedCell] subObject];
    int		location;

    [tic setStringValue:[userTitleForm stringValueAt:0]];
    [tic setDoubleValue:[userValueForm doubleValueAt:0]];

    /*
     *  Remove the tic from the list and reinsert
     *  it, to maintain the sort order of the list.
     */
    location = [ticsList[coord] addObject:[ticsList[coord] removeObject:tic]];
    [userScrollView loadCol:0 from:ticsList[coord]];
    [userMatrix scrollCellToVisible: location:0];
    [userMatrix selectCellAt: location:0];
    [self selectTic:self];

    [status reportSettingsChange:self];
    return self;
}


/*
 *  Make other controls in the window reflect the currently selected
 *  tic.  Assumes that the current tic type is TIC_USER.
 */
- selectTic:sender
{
    if (![userMatrix selectedCell]
	&& ![userMatrix multipleCellsSelected]) {

	[userMatrix selectCellAt:0:0];
      }

    [self _updateControlsForSelectedTic];
    return self;
}


// Shuts up the compiler about unused RCSId
- (const char *) rcsid
{
    return RCSId;
}


@end


@implementation UserTicsPane (Private)

- _updateControlsForSelectedTic
{
    TicCell	*singleCell = [userMatrix selectedCell];
    BOOL	enabled = (singleCell || [userMatrix multipleCellsSelected]);

    if (singleCell) {
	TicObject *tic = [singleCell subObject];

	[userTitleForm setStringValue:[tic stringValue] at:0];
	[userValueForm setDoubleValue:[tic doubleValue] at:0];

    } else {

	[userTitleForm setStringValue:"" at:0];
	[userValueForm setStringValue:"" at:0];
    }

    [deleteTicButton setEnabled:enabled];
    [modifyTicButton setEnabled:singleCell? YES:NO];
    [userValueForm selectTextAt:0];

    return self;
}


@end
